package com.triones.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils;
import com.triones.api.entity.CountryDictDO;
import com.triones.api.entity.HelpCategorizeDO;
import com.triones.api.entity.StateDictDO;
import com.triones.api.entity.interlace.dto.InterlaceCurrencyDO;
import com.triones.api.entity.vo.CountryDictVO;
import com.triones.api.entity.vo.CountryImportVo;
import com.triones.api.entity.vo.CustomMemberVO;
import com.triones.api.entity.vo.StateDictVO;
import com.triones.api.mapper.CountryDictMapper;
import com.triones.api.mapper.StateDictMapper;
import com.triones.api.service.CountryDictService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * 国家字典 -业务实现
 */
@Service
@RequiredArgsConstructor
public class CountryDictServiceImpl implements CountryDictService {

    private final CountryDictMapper countryDictMapper;

    private final StateDictMapper stateDictMapper;

    @Override
    public void importData(List<CountryImportVo> list) {
        if (list.size() > 0) {
            for (CountryImportVo countryImportVo : list) {
                LambdaQueryWrapper<CountryDictDO> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(CountryDictDO::getEnName, countryImportVo.getEnName());
                CountryDictDO countryDictDO = countryDictMapper.selectOne(wrapper);
                if (countryDictDO != null) {
                    countryDictDO.setJaName(countryImportVo.getJaName());
                    countryDictMapper.updateById(countryDictDO);
                }
            }
        }
    }

    @Override
    public List<CountryDictVO> listTree() {
        List<CountryDictVO> menuList = countryDictMapper.selectVoList(new LambdaQueryWrapper<CountryDictDO>()
            .eq(CountryDictDO::getDel, "0"));
        return this.getChildPerms(menuList, 0);
    }

    @Override
    public List<StateDictVO> stateListByCountryCode(String countryCode, String keyword) {
        return stateDictMapper.selectVoList(new LambdaQueryWrapper<StateDictDO>()
            .eq(StateDictDO::getCountryCode, countryCode)
            .and(ObjectUtil.isNotEmpty(keyword),
                rq ->
                    rq.like(StateDictDO::getCode, keyword).or()
                        .like(StateDictDO::getEnName, keyword).or()
                        .like(StateDictDO::getCnName, keyword).or()
                        .like(StateDictDO::getJaName, keyword)
            ));
    }

    @Override
    public List<StateDictVO> stateListByCountryId(Long id, String keyword) {
        return stateDictMapper.selectVoList(new LambdaQueryWrapper<StateDictDO>()
            .eq(StateDictDO::getCountryId, id).and(ObjectUtil.isNotEmpty(keyword),
                rq ->
                    rq.like(StateDictDO::getCode, keyword).or()
                        .like(StateDictDO::getEnName, keyword).or()
                        .like(StateDictDO::getCnName, keyword).or()
                        .like(StateDictDO::getJaName, keyword)
            ));
    }

    @Override
    public TableDataInfo<CountryDictVO> pageList(CountryDictDO params, PageQuery pageQuery) {
        LambdaQueryWrapper<CountryDictDO> lqw = new LambdaQueryWrapper<CountryDictDO>();
        lqw.eq(CountryDictDO::getLevel,params.getLevel())
            .eq(CountryDictDO::getDel,"0")
            .eq(CountryDictDO::getParentId,params.getParentId())
            .like(ObjectUtil.isNotEmpty(params.getCnName()),CountryDictDO::getCnName,params.getCnName())
            .like(ObjectUtil.isNotEmpty(params.getEnName()),CountryDictDO::getEnName,params.getEnName())
            .like(ObjectUtil.isNotEmpty(params.getJaName()),CountryDictDO::getJaName,params.getJaName())
            .last("ORDER BY CASE WHEN sort = 0 THEN 1 ELSE 0 END, sort ASC");
        Page<CountryDictVO> result = countryDictMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public CountryDictVO getInfo(Long id) {
        return countryDictMapper.selectVoById(id);
    }

    @Override
    public boolean checkUnique(CountryDictDO dto) {
        boolean exist = countryDictMapper.exists(new LambdaQueryWrapper<CountryDictDO>()
            .eq(CountryDictDO::getCnName, dto.getCnName())
            .eq(CountryDictDO::getDel,"0")
            .ne(ObjectUtil.isNotNull(dto.getId()), CountryDictDO::getId, dto.getId()));
        return !exist;
    }

    @Override
    public void add(CountryDictDO dto) {
        countryDictMapper.insert(dto);
    }

    @Override
    public void edit(CountryDictDO dto) {
        countryDictMapper.updateById(dto);
    }

    @Override
    public void remove(Long id) {
        CountryDictDO countryDictDO = countryDictMapper.selectById(id);
        if (countryDictDO == null) {
            throw new ServiceException("未找到该记录");
        }
        countryDictDO.setDel("1");
        countryDictMapper.updateById(countryDictDO);
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    public List<CountryDictVO> getChildPerms(List<CountryDictVO> list, int parentId) {
        List<CountryDictVO> returnList = new ArrayList<>();
        for (CountryDictVO t : list) {
            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        // 对当前层级的节点按sort排序，sort为0的排在最后
        returnList.sort(this::compareBySort);
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<CountryDictVO> list, CountryDictVO t) {
        // 得到子节点列表
        List<CountryDictVO> childList = getChildList(list, t);
        childList.sort(this::compareBySort);
        t.setChildren(childList);
        for (CountryDictVO tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 按sort字段排序的比较器
     * sort为0的排在最后，其他按升序排列
     */
    private int compareBySort(CountryDictVO a, CountryDictVO b) {
        Integer sortA = a.getSort() == null ? 0 : a.getSort();
        Integer sortB = b.getSort() == null ? 0 : b.getSort();
        if (sortA == 0 && sortB != 0) {
            return 1;
        }
        if (sortA != 0 && sortB == 0) {
            return -1;
        }
        return sortA.compareTo(sortB);
    }


    /**
     * 得到子节点列表
     */
    private List<CountryDictVO> getChildList(List<CountryDictVO> list, CountryDictVO t) {
        return StreamUtils.filter(list, n -> n.getParentId().equals(t.getId()));
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<CountryDictVO> list, CountryDictVO t) {
        return CollUtil.isNotEmpty(getChildList(list, t));
    }
}
